package com.design.pattern.singleton;

/**
 * 双重校验锁
 */
public class DoubleCheckSingleton {
    /**
     * 构造方法私有化,防止直接new实例.
     */
    private DoubleCheckSingleton() {
    }

    /**
     * 持有本类
     */
    private static DoubleCheckSingleton instance;

    /**
     * 对外暴露的方法,返回单例实例(双重校验锁)
     *
     * @return 单例实例
     */
    public synchronized static DoubleCheckSingleton getInstance() {
        //首先判断当前实例是否为null,只有第一次初始化的时候,才会为null,进入锁块,初始化实例,这样以后就不需要再次进入锁块,可以提升效率.
        if (null == instance) {
            //@1
            synchronized (DoubleCheckSingleton.class) {
                //此处直接实例化还是不安全的,因为可能有多个线程同时进入@1的位置,之后可能会实例化多次对象,这也是单锁代码块不安全的原因.
                //所以,我们需要在内部再次进行实例校验,然后再决定是否实例化对象.
               if (null==instance){
                   //此时
                   instance = new DoubleCheckSingleton();
               }
            }
        }
        return instance;
    }
}
